﻿/*************************************************************************************
 * 文 件 名:   HK_CameraCtrl
 * 
 * 描    述:   RoamingCam的摄像机控制脚本
 * 
 * 版    本：  V1.0
 * 创 建 者：  谭潇杰、京产肠饭
 * 创建时间：  2022/1/28
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using UnityEngine;
using UnityEngine.EventSystems;

public class HK_CameraCtrl : MonoBehaviour
{
    Transform parent_TF;

    public HK_MouseLook mouseLook;

    [Header("正交图移动速度"), SerializeField] float speed = 30;
    [SerializeField] Vector2 xLimitPos;
    [SerializeField] Vector2 zLimitPos;
    [Header("俯视旋转时的中心点"), SerializeField] Transform rotAroundTarget;

    // 用于记录摄像机子物体的默认高度
    [HideInInspector]
    public float initCamPosY = 0;

    void Start()
    {
        mouseLook = new HK_MouseLook();
        parent_TF = transform.parent;
        mouseLook.Init(parent_TF, transform);
        nowCamEulerX = transform.localEulerAngles.x;
        initCamPosY = transform.localPosition.y;
    }

    void OnEnable()
    {
        nowCamEulerX = 0;
    }

    float wheelValue;
    float wheelTargetValue;
    float mousex;
    float mousey;

    void Update()
    {
        //当到达目标以后取消navmesh，可以旋转相机
        if (!HK_Player.Ins.IsCanRotCam)
            return;

        // PC端操作
        if (!HK_Player.Ins.isMobile)
        {
            if (EventSystem.current.IsPointerOverGameObject())
                return;

            if (HK_Player.Ins.ViewMode == ViewMode.Roam)
            {
                mouseLook.PCLookRotation(parent_TF, transform);

                wheelValue = Input.GetAxis("Mouse ScrollWheel");

                if (wheelValue > 0)
                    wheelValue = 1f;

                if (wheelValue < 0)
                    wheelValue = -1f;

                wheelTargetValue = Mathf.Lerp(wheelTargetValue, wheelValue, 13 * Time.deltaTime);

                if (Camera.main.fieldOfView > 85 && wheelTargetValue < 0)
                    return;

                if (Camera.main.fieldOfView < 50 && wheelTargetValue > 0)
                    return;

                Camera.main.fieldOfView -= wheelTargetValue;
            }
            else if (HK_Player.Ins.ViewMode == ViewMode.BirdView)
            {
                mousex = Input.GetAxis("Mouse X");
                mousey = Input.GetAxis("Mouse Y");

                if (Input.GetMouseButton(0))
                {
                    if ((transform.position.x < xLimitPos.x && mousex > 0) || (transform.position.x > xLimitPos.y && mousex < 0))
                        return;
                    transform.position = transform.position + Vector3.left * mousex * Time.deltaTime * speed;

                    if ((transform.position.z < zLimitPos.x && mousey > 0) || (transform.position.z > zLimitPos.y && mousey < 0))
                        return;
                    transform.position = transform.position + Vector3.back * mousey * Time.deltaTime * speed;
                }
            }
            else if (HK_Player.Ins.ViewMode == ViewMode.ThreeD)
            {
                CameraRotate();
                CameraFOV();
            }
        }
        else // 移动端操作
        {
            if (Input.touchCount >= 1 && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
                return;

            if (HK_Player.Ins.ViewMode == ViewMode.Roam)
                mouseLook.MobileLookRoatation(parent_TF, transform);
            if (HK_Player.Ins.ViewMode == ViewMode.BirdView)
                BirdViewTouchMove();
            if (HK_Player.Ins.ViewMode == ViewMode.ThreeD)
                ThreeDTouchMove();
        }
    }

    #region 鼠标操作
    Vector2 mouseLerpPos;
    [SerializeField] float wheelSpeed;
    [SerializeField] float minDist;
    [SerializeField] float maxDist;
    [Header("最大俯仰角：")]
    [SerializeField] float maxAngle;
    [Header("最小俯仰角：")]
    [SerializeField] float minAngle;
    // 当前摄像机俯仰角
    float nowCamEulerX;
    [SerializeField] float rotateSpeed;

    /// <summary>
    /// 摄像机旋转
    /// </summary>
    void CameraRotate()
    {
        mousex = Input.GetAxis("Mouse X");
        mousey = Input.GetAxis("Mouse Y");

        if (Input.GetMouseButton(0))
        {
            mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, mousex, 5 * Time.deltaTime);
            mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, mousey, 5 * Time.deltaTime);
        }
        else
        {
            mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, 0, 5 * Time.deltaTime);
            mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, 0, 5 * Time.deltaTime);
        }
        transform.RotateAround(rotAroundTarget.position, Vector3.up, mouseLerpPos.x * rotateSpeed);
        nowCamEulerX -= mouseLerpPos.y * rotateSpeed;

        if (nowCamEulerX > maxAngle || nowCamEulerX < minAngle)
        {
            nowCamEulerX += mouseLerpPos.y * rotateSpeed;

            mouseLerpPos.y = 0;
            return;
        }

        if (Mathf.Abs(-mouseLerpPos.y * rotateSpeed) < 0.02f)
            return;

        transform.RotateAround(rotAroundTarget.position, transform.right, -mouseLerpPos.y * rotateSpeed * 0.5f);
    }

    /// <summary>
    /// 摄像机缩放
    /// </summary>
    void CameraFOV()
    {
        wheelValue = Input.GetAxis("Mouse ScrollWheel");

        if (Vector3.Distance(transform.position, rotAroundTarget.position) < minDist && wheelValue > 0)
            return;

        if (Vector3.Distance(transform.position, rotAroundTarget.position) > maxDist && wheelValue < 0)
            return;

        if (wheelValue > 0)
            wheelValue = 0.15f;

        if (wheelValue < 0)
            wheelValue = -0.15f;

        wheelTargetValue = Mathf.Lerp(wheelTargetValue, wheelValue, 5 * Time.deltaTime);

        transform.Translate(Vector3.forward * wheelTargetValue * wheelSpeed);
    }

    #endregion

    Vector2 targetPos;
    Touch touch1;
    Touch touch2;
    Vector2 targetTouchPos = Vector2.zero;
    Vector2 lerpTouchPos = Vector2.zero;
    float doubleTouchCurDis;
    float doubleTouchLastDis;
    float dis;

    void ThreeDTouchMove()
    {
        if (Input.touchCount > 1 && (Input.touches[0].phase == TouchPhase.Moved || Input.touches[1].phase == TouchPhase.Moved))
        {
            touch1 = Input.GetTouch(0);
            touch2 = Input.GetTouch(1);
            doubleTouchCurDis = Vector2.Distance(touch1.position, touch2.position);
            // 前进的时候是 + 后退的时候是 -
            dis = (doubleTouchCurDis - doubleTouchLastDis);

            if (Vector3.Distance(transform.position, rotAroundTarget.position) < minDist && dis > 0)
            {
                doubleTouchLastDis = doubleTouchCurDis;
                return;
            }
            if (Vector3.Distance(transform.position, rotAroundTarget.position) > maxDist && dis < 0)
            {
                doubleTouchLastDis = doubleTouchCurDis;
                return;
            }

            if (Mathf.Abs(dis) < 10f)
                dis = 0;

            if (Mathf.Abs(dis) > 10)
            {
                if (dis < 0)
                    dis = -20;
                else
                    dis = 20;
            }

            doubleTouchLastDis = doubleTouchCurDis;
        }
        else
        {
            if (dis != 0)
                dis = 0;
        }
        wheelTargetValue = Mathf.Lerp(wheelTargetValue, dis * wheelSpeed / 100, 6f * Time.deltaTime);

        if (Mathf.Abs(wheelTargetValue) < 0.15f)
            wheelTargetValue = 0f;
        transform.Translate(Vector3.forward * wheelTargetValue * 0.5f);

        if (Mathf.Abs(wheelTargetValue) > 0.03f)
            return;

        //----------------------单指触摸旋转---------------------------
        if (Input.touchCount == 1)
        {
            if (Input.touches[0].phase == TouchPhase.Began)
            {
                targetTouchPos = Vector2.zero;
            }

            if (Input.touches[0].phase == TouchPhase.Moved)
            {
                targetTouchPos.x = Input.touches[0].deltaPosition.x * 0.05f;
                targetTouchPos.y = Input.touches[0].deltaPosition.y * 0.05f;
            }

            if (Input.touches[0].phase == TouchPhase.Ended)
            {
                targetTouchPos = Vector2.zero;
            }
        }

        lerpTouchPos = targetTouchPos;

        transform.RotateAround(rotAroundTarget.position, Vector3.up, -lerpTouchPos.x * rotateSpeed);

        nowCamEulerX += lerpTouchPos.y * rotateSpeed;

        if (nowCamEulerX > maxAngle || nowCamEulerX < minAngle)
        {
            nowCamEulerX -= lerpTouchPos.y * rotateSpeed;
            targetTouchPos = Vector2.zero;
            return;
        }
        transform.RotateAround(rotAroundTarget.position, transform.right, lerpTouchPos.y * rotateSpeed * 0.5f);
    }
    void BirdViewTouchMove()
    {
        //一个手指 控制移动
        if (Input.touchCount == 1)
        {
            if (Input.touches[0].phase == TouchPhase.Began)
            {
                targetPos = Vector2.zero;
            }
            if (Input.touches[0].phase == TouchPhase.Moved)
            {
                targetPos.x = Input.touches[0].deltaPosition.x * 0.3f;
                targetPos.y = Input.touches[0].deltaPosition.y * 0.3f;
            }
            if (Input.touches[0].phase == TouchPhase.Ended)
            {
                targetPos = Vector2.zero;
            }
            if ((transform.position.x > xLimitPos.x && targetPos.x > 0) || (transform.position.x < xLimitPos.y && targetPos.x < 0)) return;
            if ((transform.position.z < zLimitPos.x && targetPos.y < 0) || (transform.position.z > zLimitPos.y && targetPos.y > 0)) return;

            transform.position += new Vector3(targetPos.x * Time.deltaTime * 5, 0, targetPos.y * Time.deltaTime * 5);
        }
    }
}
